//
// Created by EDZ on 2020/3/3.
//

#include "AudioChannel.h"

AudioChannel::AudioChannel() {

}

AudioChannel::~AudioChannel() {

}

void AudioChannel::initAudioEncoder(int sample_rate, int channels) {
    mChannels = channels;

    /**
     * 采样率，通道数， 编码时最大样本数， 最大输出个数（字节数）
     */
    audioEncoder = faacEncOpen(sample_rate, channels, &inputSamples, &maxOutputBytes);

    faacEncConfigurationPtr config = faacEncGetCurrentConfiguration(audioEncoder); // 获取当前编码器配置

    config->mpegVersion = MPEG4; // 使用mpeg-4标准
    config->aacObjectType = LOW; // LC 低复杂度
    config->inputFormat = FAAC_INPUT_16BIT;
    config->outputFormat = 0;// 需要原始数据，而不是adts
    config->useTns = 1; // 降噪
    config->useLfe = 0; // 环绕声

    int ret = faacEncSetConfiguration(audioEncoder, config);
    if(!ret){
        LOGE("音频编码器配置失败");
        return;
    }

    // 初始化输出缓冲区
    buffer = new u_char[maxOutputBytes];
}

void AudioChannel::encodeData(int8_t *data) {
    // faac编码，返回编码后数据的字节长度
    int byteLen = faacEncEncode(audioEncoder, reinterpret_cast<int32_t *>(data), inputSamples, buffer, maxOutputBytes);
    if(byteLen > 0){
        LOGE("音频编码成功");
        // 组rtmp包
        RTMPPacket *packet = new RTMPPacket;
        // 参考。。
        int body_size = 2 + byteLen;
        RTMPPacket_Alloc(packet, body_size);
        int i = 0;
        packet->m_body[0] = 0xAF; // 双声道
        if(mChannels == 1){
            packet->m_body[0] = 0xAE; // 单声道
        }

        packet->m_body[1] = 0x01;
        memcpy(&packet->m_body[2], buffer, byteLen);

        packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;
        packet->m_nBodySize = body_size;
        packet->m_nTimeStamp = -1;
        packet->m_hasAbsTimestamp = 1;
        packet->m_nChannel = 11;
        packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
        // 完成封包

        // 发包
        audioCallback(packet);
    }
}

int AudioChannel::getInputSamples() {
    return inputSamples;
}

void AudioChannel::setAudioCallback(AudioChannel::AudioCallback callback) {
    audioCallback = callback;
}

/**
 * 发送解码头
 * @return
 */
RTMPPacket *AudioChannel::getAudioSeqHeader() {
    u_char *ppBuffer;
    u_long byteLen;
    faacEncGetDecoderSpecificInfo(audioEncoder, &ppBuffer, &byteLen);

    // 组rtmp包
    RTMPPacket *packet = new RTMPPacket;
    // 参考。。
    int body_size = 2 + byteLen;
    RTMPPacket_Alloc(packet, body_size);
    int i = 0;
    packet->m_body[0] = 0xAF; // 双声道
    if(mChannels == 1){
        packet->m_body[0] = 0xAE; // 单声道
    }

    packet->m_body[1] = 0x00; // 序列头配置信息为00
    memcpy(&packet->m_body[2], ppBuffer, byteLen);

    packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;
    packet->m_nBodySize = body_size;
    packet->m_nTimeStamp = 0;
    packet->m_hasAbsTimestamp = 1;
    packet->m_nChannel = 11;
    packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
    // 完成封包

    // 发包
    audioCallback(packet);

    return nullptr;
}
